package com.lineage.server.world;

import com.lineage.config.Config;
import com.lineage.server.datatables.DoorSpawnTable;
import com.lineage.server.datatables.MapsTable;
import com.lineage.server.model.Instance.L1BowInstance;
import com.lineage.server.model.Instance.L1CrockInstance;
import com.lineage.server.model.Instance.L1DeInstance;
import com.lineage.server.model.Instance.L1DollInstance;
import com.lineage.server.model.Instance.L1DoorInstance;
import com.lineage.server.model.Instance.L1EffectInstance;
import com.lineage.server.model.Instance.L1HierarchInstance;
import com.lineage.server.model.Instance.L1ItemInstance;
import com.lineage.server.model.Instance.L1MonsterInstance;
import com.lineage.server.model.Instance.L1NpcInstance;
import com.lineage.server.model.Instance.L1PcInstance;
import com.lineage.server.model.Instance.L1PetInstance;
import com.lineage.server.model.Instance.L1SummonInstance;
import com.lineage.server.model.Instance.L1TrapInstance;
import com.lineage.server.model.L1GroundInventory;
import com.lineage.server.model.L1Location;
import com.lineage.server.model.L1Object;
import com.lineage.server.model.map.L1Map;
import com.lineage.server.serverpackets.S_SystemMessage;
import com.lineage.server.serverpackets.ServerBasePacket;
import com.lineage.server.templates.L1Npc;
import com.lineage.server.types.Point;
import com.lineage.server.utils.collections.CTRAssignLock;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class World {
  private static final Map<Integer, L1ItemInstance> pcFallingItemObjIdList = new HashMap<>();
  
  static {
    _log = LogFactory.getLog(World.class);
  }
  
  private int _weather = 4;
  
  private boolean _worldChatEnabled = true;
  
  private boolean _processingContributionTotal = false;
  
  private final ConcurrentHashMap<String, L1PcInstance> _allPlayers = new ConcurrentHashMap<>();
  
  private final ConcurrentHashMap<Integer, L1Object> _allObjects = new ConcurrentHashMap<>();
  
  private final HashMap<Integer, ConcurrentHashMap<Integer, L1Object>> _visibleObjects = new HashMap<>();
  
  private static final Log _log;
  
  private static final int MAX_MAP_ID = 12000;
  
  private static World _instance;
  
  private Collection<L1Object> _allValues;
  
  private Collection<L1PcInstance> _allPlayerValues;
  
  public World() {
    Iterator<Integer> iterator = MapsTable.get().getMaps().keySet().iterator();
    while (iterator.hasNext()) {
      Integer mapid = iterator.next();
      ConcurrentHashMap<Integer, L1Object> map = new ConcurrentHashMap<>();
      this._visibleObjects.put(mapid, map);
      CTRAssignLock.registerGrdIvnLock(mapid);
    } 
    _log.info("游戏世界储存中心建立完成!!!");
  }
  
  public static void addpcFallingItemObjIdList(L1ItemInstance item) {
    L1ItemInstance fallingItem = new L1ItemInstance(item.getItem(), item.getCount());
    fallingItem.set_char_objid(item.get_char_objid());
    pcFallingItemObjIdList.put(Integer.valueOf(item.getId()), fallingItem);
  }
  
  public static boolean checkpcFallingItem(int objid) {
    return pcFallingItemObjIdList.containsKey(Integer.valueOf(objid));
  }
  
  public static L1ItemInstance getPcFallingItem(int objid) {
    return pcFallingItemObjIdList.get(Integer.valueOf(objid));
  }
  
  public static void removepcFallingItemObjId(int objid) {
    pcFallingItemObjIdList.remove(Integer.valueOf(objid));
  }
  
  public static World get() {
    if (_instance == null) {
      _instance = new World(); 
    }
    return _instance;
  }
  
  private static boolean check(L1PcInstance tgpc) {
    try {
      if (tgpc == null)
        return false; 
      if (tgpc.getOnlineStatus() == 0)
        return false; 
      if (tgpc.getNetConnection() == null)
        return false; 
    } catch (Exception e) {
      return false;
    } 
    return true;
  }
  
  public Object getRegion(Object object) {
    return null;
  }
  
  public void clear() {
    _instance = new World();
  }
  
  public void storeObject(L1Object object) {
    try {
      if (object == null)
        throw new NullPointerException(); 
      this._allObjects.put(Integer.valueOf(object.getId()), object);
      if (object instanceof L1ItemInstance)
        WorldItem.get().put(new Integer(object.getId()), (L1ItemInstance)object); 
      if (object instanceof L1PcInstance) {
        L1PcInstance pc = (L1PcInstance)object;
        if (pc.isCrown()) {
          WorldCrown.get().put(new Integer(pc.getId()), pc);
        } else if (pc.isKnight()) {
          WorldKnight.get().put(new Integer(pc.getId()), pc);
        } else if (pc.isElf()) {
          WorldElf.get().put(new Integer(pc.getId()), pc);
        } else if (pc.isWizard()) {
          WorldWizard.get().put(new Integer(pc.getId()), pc);
        } else if (pc.isDarkelf()) {
          WorldDarkelf.get().put(new Integer(pc.getId()), pc);
        } else if (pc.isDragonKnight()) {
          WorldDragonKnight.get().put(new Integer(pc.getId()), pc);
        } else if (pc.isIllusionist()) {
          WorldIllusionist.get().put(new Integer(pc.getId()), pc);
        } 
        this._allPlayers.put(pc.getName(), pc);
      } 
      if (object instanceof L1DeInstance) {
        L1DeInstance de = (L1DeInstance)object;
        WorldDe.get().put(de.getNameId(), de);
      } 
      if (object instanceof L1TrapInstance)
        WorldTrap.get().put(new Integer(object.getId()), (L1TrapInstance)object); 
      if (object instanceof L1PetInstance)
        WorldPet.get().put(new Integer(object.getId()), (L1PetInstance)object); 
      if (object instanceof L1SummonInstance)
        WorldSummons.get().put(new Integer(object.getId()), (L1SummonInstance)object); 
      if (object instanceof L1DollInstance)
        WorldDoll.get().put(new Integer(object.getId()), (L1DollInstance)object); 
      if (object instanceof L1EffectInstance)
        WorldEffect.get().put(new Integer(object.getId()), (L1EffectInstance)object); 
      if (object instanceof L1MonsterInstance)
        WorldMob.get().put(new Integer(object.getId()), (L1MonsterInstance)object); 
      if (object instanceof L1HierarchInstance)
        WorldHierarch.get().put(new Integer(object.getId()), (L1HierarchInstance)object); 
      if (object instanceof L1BowInstance)
        WorldBow.get().put(new Integer(object.getId()), (L1BowInstance)object); 
      if (object instanceof L1NpcInstance)
        WorldNpc.get().put(new Integer(object.getId()), (L1NpcInstance)object); 
      if (object instanceof L1CrockInstance)
        WorldCrock.get().put((new Integer(object.getId())).intValue(), (L1CrockInstance)object); 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
	public void removeObject(final L1Object object) {
		// System.out.println("移出世界");
		try {
			if (object == null) {
				throw new NullPointerException();
			}

			_allObjects.remove(object.getId());

			if (object instanceof L1ItemInstance) {
				WorldItem.get().remove(new Integer(object.getId()));
			}

			if (object instanceof L1PcInstance) {
				final L1PcInstance pc = (L1PcInstance) object;

				if (pc.isCrown()) {
					WorldCrown.get().remove(new Integer(pc.getId()));

				} else if (pc.isKnight()) {
					WorldKnight.get().remove(new Integer(pc.getId()));

				} else if (pc.isElf()) {
					WorldElf.get().remove(new Integer(pc.getId()));

				} else if (pc.isWizard()) {
					WorldWizard.get().remove(new Integer(pc.getId()));

				} else if (pc.isDarkelf()) {
					WorldDarkelf.get().remove(new Integer(pc.getId()));

				} else if (pc.isDragonKnight()) {
					WorldDragonKnight.get().remove(new Integer(pc.getId()));

				} else if (pc.isIllusionist()) {
					WorldIllusionist.get().remove(new Integer(pc.getId()));
				}
				_allPlayers.remove(pc.getName());
			}
			// DE
			if (object instanceof L1DeInstance) {
				L1DeInstance de = (L1DeInstance) object;
				WorldDe.get().remove(de.getNameId());
			}
			// 陷阱
			if (object instanceof L1TrapInstance) {
				WorldTrap.get().remove(new Integer(object.getId()));
			}
			// 宠物
			if (object instanceof L1PetInstance) {
				WorldPet.get().remove(new Integer(object.getId()));
			}
			// 召唤兽
			if (object instanceof L1SummonInstance) {
				WorldSummons.get().remove(new Integer(object.getId()));
			}
			// 魔法娃娃
			if (object instanceof L1DollInstance) {
				WorldDoll.get().remove(new Integer(object.getId()));
			}
			// 祭司
			if ((object instanceof L1HierarchInstance)) {
				WorldHierarch.get().remove(new Integer(object.getId()));
			}
			// Effect(技能物件)
			if (object instanceof L1EffectInstance) {
				WorldEffect.get().remove(new Integer(object.getId()));
			}
			// MOB
			if (object instanceof L1MonsterInstance) {
				WorldMob.get().remove(new Integer(object.getId()));
			}
			// BOW
			if (object instanceof L1BowInstance) {
				WorldBow.get().remove(new Integer(object.getId()));
			}
			// NPC
			if (object instanceof L1NpcInstance) {
				WorldNpc.get().remove(new Integer(object.getId()));
			}
			// 时空裂痕
			if (object instanceof L1CrockInstance) {
				WorldCrock.get().remove(new Integer(object.getId()));
			}
			
		} catch (final Exception e) {
			_log.error(e.getLocalizedMessage(), e);
		}
	}
  
  public L1Object findObject(int oID) {
    if (oID == 0)
      return null; 
    return this._allObjects.get(Integer.valueOf(oID));
  }
  
  public Collection<L1Object> getObject() {
    try {
      Collection<L1Object> vs = this._allValues;
      return (vs != null) ? vs : (
        this._allValues = Collections.unmodifiableCollection(this._allObjects.values()));
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
      return null;
    } 
  }
  
  public L1GroundInventory getInventory(int x, int y, short map) {
    try {
      int inventoryKey = ((x - 30000) * 10000 + y - 30000) * -1;
      ConcurrentHashMap<Integer, L1Object> idmap = this._visibleObjects.get(new Integer(map));
      if (idmap != null) {
        Object object = idmap.get(Integer.valueOf(inventoryKey));
        if (object == null)
          return new L1GroundInventory(inventoryKey, x, y, map); 
        return (L1GroundInventory)object;
      } 
      _log.error("游戏世界储存中心并未建立该地图编号资料档案: " + map);
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
    return null;
  }
  
  public L1GroundInventory getInventory(L1Location loc) {
    return getInventory(loc.getX(), loc.getY(), (short)loc.getMap().getId());
  }
  
  public void addVisibleObject(L1Object object) {
    try {
      ConcurrentHashMap<Integer, L1Object> map = this._visibleObjects.get(new Integer(object.getMapId()));
      if (map != null) {
        map.put(Integer.valueOf(object.getId()), object);
      } else {
        _log.error("游戏世界储存中心并未建立该地图编号资料档案: " + object.getMapId());
      } 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
	public void removeVisibleObject(final L1Object object) {
		try {
			final ConcurrentHashMap<Integer, L1Object> map = _visibleObjects
					.get(new Integer(object.getMapId()));
			if (map != null) {
				map.remove(object.getId());

			} else {
				_log.error("游戏世界储存中心并未建立该地图编号资料档案: " + object.getMapId());
			}

		} catch (final Exception e) {
			_log.error(e.getLocalizedMessage(), e);
		}
	}
  
	public void moveVisibleObject(final L1Object object, final int newMapId) {// set_Mapで新しいMapにするまえに呼ぶこと
		try {
			int srcMapId = object.getMapId();
			if (srcMapId != newMapId) {
				// 取回原地图资料
				final ConcurrentHashMap<Integer, L1Object> mapSrc = _visibleObjects
						.get(new Integer(srcMapId));
				if (mapSrc != null) {
					mapSrc.remove(object.getId());

				} else {
					_log.error("游戏世界储存中心并未建立该地图编号资料档案: " + srcMapId);
				}

				// 取回新地图资料
				final ConcurrentHashMap<Integer, L1Object> map = _visibleObjects
						.get(new Integer(newMapId));
				if (map != null) {
					map.put(object.getId(), object);

				} else {
					_log.error("游戏世界储存中心并未建立该地图编号资料档案: " + newMapId);
				}
			}

		} catch (final Exception e) {
			_log.error(e.getLocalizedMessage(), e);
		}
	}
  
  private HashMap<Integer, Integer> createLineMap(Point src, Point target) {
    HashMap<Integer, Integer> lineMap = new HashMap<>();
    int x0 = src.getX();
    int y0 = src.getY();
    int x2 = target.getX();
    int y2 = target.getY();
    int sx = (x2 > x0) ? 1 : -1;
    int dx = (x2 > x0) ? (x2 - x0) : (x0 - x2);
    int sy = (y2 > y0) ? 1 : -1;
    int dy = (y2 > y0) ? (y2 - y0) : (y0 - y2);
    int x3 = x0;
    int y3 = y0;
    if (dx >= dy) {
      int E = -dx;
      int i = 0;
      while (i <= dx) {
        int key = (x3 << 16) + y3;
        lineMap.put(Integer.valueOf(key), Integer.valueOf(key));
        x3 += sx;
        E += dy << 1;
        if (E >= 0) {
          y3 += sy;
          E -= dx << 1;
        } 
        i++;
      } 
    } else {
      int E = -dy;
      int i = 0;
      while (i <= dy) {
        int key = (x3 << 16) + y3;
        lineMap.put(Integer.valueOf(key), Integer.valueOf(key));
        y3 += sy;
        E += dx << 1;
        if (E >= 0) {
          x3 += sx;
          E -= dy << 1;
        } 
        i++;
      } 
    } 
    return lineMap;
  }
  
  public ArrayList<L1Object> getVisibleLineObjects(L1Object src, L1Object target) {
    try {
      HashMap<Integer, Integer> lineMap = createLineMap((Point)src.getLocation(), (Point)target.getLocation());
      int map = target.getMapId();
      ArrayList<L1Object> result = new ArrayList<>();
      ConcurrentHashMap<Integer, L1Object> mapSrc = this._visibleObjects.get(new Integer(map));
      if (mapSrc == null) {
        _log.error("游戏世界储存中心并未建立该地图编号资料档案: " + map);
        return result;
      } 
      Iterator<L1Object> iterator = mapSrc.values().iterator();
      while (iterator.hasNext()) {
        L1Object element = iterator.next();
        if (element.equals(src))
          continue; 
        if (src.get_showId() != element.get_showId())
          continue; 
        int key = (element.getX() << 16) + element.getY();
        if (!lineMap.containsKey(Integer.valueOf(key)))
          continue; 
        result.add(element);
      } 
      lineMap.clear();
      return result;
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
      return null;
    } 
  }
  
  public ArrayList<L1Object> getVisibleBoxObjects(L1Object object, int heading, int width, int height) {
    int x = object.getX();
    int y = object.getY();
    int map = object.getMapId();
    L1Location location = object.getLocation();
    ArrayList<L1Object> result = new ArrayList<>();
	final int headingRotate[] = { 6, 7, 0, 1, 2, 3, 4, 5 };
    double cosSita = Math.cos(headingRotate[heading] * Math.PI / 4.0D);
    double sinSita = Math.sin(headingRotate[heading] * Math.PI / 4.0D);
    ConcurrentHashMap<Integer, L1Object> mapSrc = this._visibleObjects.get(new Integer(map));
    if (mapSrc == null) {
      _log.error("游戏世界储存中心并未建立该地图编号资料档案: " + map);
      return result;
    } 
    Iterator<L1Object> iterator = mapSrc.values().iterator();
    while (iterator.hasNext()) {
      L1Object element = iterator.next();
      if (element.equals(object))
        continue; 
      if (object.get_showId() != element.get_showId())
        continue; 
      if (map != element.getMapId())
        continue; 
      if (location.isSamePoint((Point)element.getLocation())) {
        result.add(element);
        continue;
      } 
      int distance = location.getTileLineDistance((Point)element.getLocation());
      if (distance > height && distance > width)
        continue; 
      int x2 = element.getX() - x;
      int y2 = element.getY() - y;
      int rotX = (int)Math.round(x2 * cosSita + y2 * sinSita);
      int rotY = (int)Math.round(-x2 * sinSita + y2 * cosSita);
      int xmin = 0;
      int xmax = height;
      int ymin = -width;
      int ymax = width;
      if (rotX <= 0 || distance > xmax || rotY < ymin || rotY > ymax)
        continue; 
      result.add(element);
    } 
    return result;
  }
  
  public ArrayList<L1Object> getVisibleObjects(L1Object object) {
    return getVisibleObjects(object, -1);
  }
  
  public boolean getVisibleObjects(L1Object src, L1Object tg) {
    return (src.get_showId() == tg.get_showId() && src.getMapId() == tg.getMapId() && 
      src.getLocation().isInScreen((Point)tg.getLocation()));
  }
  
  public ArrayList<L1Object> getVisibleObjects(L1Object object, int radius) {
    L1Map map = object.getMap();
    L1Location l1Location = object.getLocation();
    ArrayList<L1Object> result = new ArrayList<>();
    ConcurrentHashMap<Integer, L1Object> mapSrc = this._visibleObjects.get(new Integer(map.getId()));
    if (mapSrc == null) {
      _log.error("游戏世界储存中心并未建立该地图编号资料档案: " + map.getId());
      return result;
    } 
    Iterator<L1Object> iterator = mapSrc.values().iterator();
    while (iterator.hasNext()) {
      L1Object element = iterator.next();
      if (element.equals(object))
        continue; 
      if (object.get_showId() != element.get_showId()) {
        boolean is = false;
        if (element instanceof com.lineage.server.model.Instance.L1MerchantInstance)
          is = true; 
        if (element instanceof com.lineage.server.model.Instance.L1DwarfInstance)
          is = true; 
        if (!is)
          continue; 
      } 
      if (map != element.getMap())
        continue; 
      switch (radius) {
        case -1:
          if (l1Location.isInScreen((Point)element.getLocation()))
            result.add(element); 
          continue;
        case 0:
          if (l1Location.isSamePoint((Point)element.getLocation()))
            result.add(element); 
          continue;
      } 
      int r = l1Location.getTileLineDistance((Point)element.getLocation());
      if (r <= radius)
        result.add(element); 
    } 
    return result;
  }
  
  public ArrayList<L1Object> getVisiblePoint(L1Location loc, int radius, int showid) {
    ArrayList<L1Object> result = new ArrayList<>();
    int mapId = loc.getMapId();
    ConcurrentHashMap<Integer, L1Object> mapSrc = this._visibleObjects.get(new Integer(mapId));
    if (mapSrc == null) {
      _log.error("游戏世界储存中心并未建立该地图编号资料档案: " + mapId);
      return result;
    } 
    Iterator<L1Object> iterator = mapSrc.values().iterator();
    while (iterator.hasNext()) {
      L1Object element = iterator.next();
      if (mapId != element.getMapId())
        continue; 
      if (showid != element.get_showId())
        continue; 
      if (loc.getTileLineDistance((Point)element.getLocation()) > radius)
        continue; 
      result.add(element);
    } 
    return result;
  }
  
  public ArrayList<L1PcInstance> getVisiblePc(L1Location loc) {
    ArrayList<L1PcInstance> result = new ArrayList<>();
    int mapId = loc.getMapId();
    ConcurrentHashMap<Integer, L1Object> mapSrc = this._visibleObjects.get(new Integer(mapId));
    if (mapSrc == null) {
      _log.error("游戏世界储存中心并未建立该地图编号资料档案: " + mapId);
      return result;
    } 
    Iterator<L1PcInstance> iterator = this._allPlayers.values().iterator();
    while (iterator.hasNext()) {
      L1PcInstance element = iterator.next();
      if (mapId != element.getMapId())
        continue; 
      if (!loc.isInScreen((Point)element.getLocation()))
        continue; 
      result.add(element);
    } 
    return result;
  }
  
  public ArrayList<L1PcInstance> getVisiblePlayer(L1Object object) {
    return getVisiblePlayer(object, -1);
  }
  
  public ArrayList<L1PcInstance> getVisiblePlayer(L1Object object, int radius) {
    int map = object.getMapId();
    L1Location l1Location = object.getLocation();
    ArrayList<L1PcInstance> result = new ArrayList<>();
    Iterator<L1PcInstance> iterator = this._allPlayers.values().iterator();
    while (iterator.hasNext()) {
      L1PcInstance element = iterator.next();
      if (element.equals(object))
        continue; 
      if (map != element.getMapId())
        continue; 
      if (object.get_showId() != element.get_showId())
        continue; 
      switch (radius) {
        case -1:
          if (l1Location.isInScreen((Point)element.getLocation()))
            result.add(element); 
          continue;
        case 0:
          if (l1Location.isSamePoint((Point)element.getLocation()))
            result.add(element); 
          continue;
      } 
      if (l1Location.getTileLineDistance((Point)element.getLocation()) <= radius)
        result.add(element); 
    } 
    return result;
  }
  
  public ArrayList<L1PcInstance> getVisiblePlayerExceptTargetSight(L1Object object, L1Object target) {
    int map = object.getMapId();
    L1Location l1Location1 = object.getLocation();
    L1Location l1Location2 = target.getLocation();
    ArrayList<L1PcInstance> result = new ArrayList<>();
    Iterator<L1PcInstance> iterator = this._allPlayers.values().iterator();
    while (iterator.hasNext()) {
      L1PcInstance element = iterator.next();
      if (element.equals(object))
        continue; 
      if (map != element.getMapId())
        continue; 
      if (target.get_showId() != element.get_showId())
        continue; 
      if (Config.PC_RECOGNIZE_RANGE == -1) {
        if (!l1Location1.isInScreen((Point)element.getLocation()) || l1Location2.isInScreen((Point)element.getLocation()))
          continue; 
        result.add(element);
        continue;
      } 
      if (l1Location1.getTileLineDistance((Point)element.getLocation()) > Config.PC_RECOGNIZE_RANGE || 
        l1Location2.getTileLineDistance((Point)element.getLocation()) <= Config.PC_RECOGNIZE_RANGE)
        continue; 
      result.add(element);
    } 
    return result;
  }
  
  public ArrayList<L1PcInstance> getVisiblePlayerExceptTargetSight(L1Object object, L1Object target, int radius) {
    int map = object.getMapId();
    L1Location l1Location1 = object.getLocation();
    L1Location l1Location2 = target.getLocation();
    ArrayList<L1PcInstance> result = new ArrayList<>();
    Iterator<L1PcInstance> iterator = this._allPlayers.values().iterator();
    while (iterator.hasNext()) {
      L1PcInstance element = iterator.next();
      if (element.equals(object))
        continue; 
      if (map != element.getMapId())
        continue; 
      if (target.get_showId() != element.get_showId())
        continue; 
      if (l1Location1.getTileLineDistance((Point)element.getLocation()) > radius || 
        l1Location2.getTileLineDistance((Point)element.getLocation()) > radius)
        continue; 
      result.add(element);
    } 
    return result;
  }
  
  public ArrayList<L1PcInstance> getRecognizePlayer(L1Object object) {
    return getVisiblePlayer(object, Config.PC_RECOGNIZE_RANGE);
  }
  
  public Collection<L1PcInstance> getAllPlayers() {
    try {
      Collection<L1PcInstance> vs = this._allPlayerValues;
      return (vs != null) ? vs : (
        this._allPlayerValues = Collections.unmodifiableCollection(this._allPlayers.values()));
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
      return null;
    } 
  }
  
  public int checkPcCountForAccount(String accountName) {
    int count = 0;
    Iterator<L1PcInstance> iterator = getAllPlayers().iterator();
    while (iterator.hasNext()) {
      L1PcInstance tgpc = iterator.next();
      if (tgpc.getAccountName().equals(accountName))
        count++; 
    } 
    return count;
  }
  
  public L1PcInstance getPlayer(String name) {
    if (this._allPlayers.contains(name))
      return this._allPlayers.get(name); 
    Iterator<L1PcInstance> iterator = getAllPlayers().iterator();
    while (iterator.hasNext()) {
      L1PcInstance each = iterator.next();
      if (each.getName().equalsIgnoreCase(name))
        return each; 
    } 
    return null;
  }
  
  public boolean get_pc(L1PcInstance pc, String name) {
    L1PcInstance tg = this._allPlayers.get(name);
    return (tg != null && pc.getLocation().isInScreen((Point)tg.getLocation()));
  }
  
  public final Map<Integer, L1Object> getAllVisibleObjects() {
    return this._allObjects;
  }
  
  public final HashMap<Integer, ConcurrentHashMap<Integer, L1Object>> getVisibleObjects() {
    return this._visibleObjects;
  }
  
  public final ConcurrentHashMap<Integer, L1Object> getVisibleObjects(int mapId) {
    return this._visibleObjects.get(new Integer(mapId));
  }
  
  public int getWeather() {
    return this._weather;
  }
  
  public void setWeather(int weather) {
    this._weather = weather;
  }
  
  public void set_worldChatElabled(boolean flag) {
    this._worldChatEnabled = flag;
  }
  
  public boolean isWorldChatElabled() {
    return this._worldChatEnabled;
  }
  
  public boolean isProcessingContributionTotal() {
    return this._processingContributionTotal;
  }
  
  public void setProcessingContributionTotal(boolean flag) {
    this._processingContributionTotal = flag;
  }
  
  public void broadcastPacketToAll(ServerBasePacket packet) {
    Iterator<L1PcInstance> iter = getAllPlayers().iterator();
    while (iter.hasNext()) {
      L1PcInstance tgpc = iter.next();
      if (check(tgpc))
        tgpc.sendPackets(packet); 
    } 
  }
  
  public void broadcastServerMessage(String message) {
    broadcastPacketToAll((ServerBasePacket)new S_SystemMessage(message));
  }
  
  public ArrayList<L1Object> getVisiblePoint(L1Location loc, int radius) {
    ArrayList<L1Object> result = new ArrayList<>();
    int mapId = loc.getMapId();
    ConcurrentHashMap<Integer, L1Object> mapSrc = this._visibleObjects.get(new Integer(mapId));
    if (mapSrc == null) {
      _log.error("游戏世界储存中心并未建立该地图编号资料档案: " + mapId);
      return result;
    } 
    if (mapId <= 12000) {
      Iterator<L1Object> iterator = mapSrc.values().iterator();
      while (iterator.hasNext()) {
        L1Object element = iterator.next();
        if (mapId != element.getMapId())
          continue; 
        if (loc.getTileLineDistance((Point)element.getLocation()) > radius)
          continue; 
        result.add(element);
      } 
    } 
    return result;
  }
  
  public void closeMap(int mapid) {
    Iterator<Map.Entry<Integer, L1Object>> iterator = this._allObjects.entrySet().iterator();
    while (iterator.hasNext()) {
      Map.Entry<Integer, L1Object> entry = iterator.next();
      L1Object object = entry.getValue();
      if (object.getMapId() == mapid) {
        if (object instanceof L1DoorInstance)
          DoorSpawnTable.get().removeDoor((L1DoorInstance)object); 
        removeObject(object);
      } 
    } 
    ConcurrentHashMap<Integer, L1Object> map = new ConcurrentHashMap<>();
    this._visibleObjects.put(Integer.valueOf(mapid), map);
  }
  
  public void broadcastPacketToAlldroplist(ServerBasePacket packet) {
    Iterator<L1PcInstance> iterator = getAllPlayers().iterator();
    while (iterator.hasNext()) {
      L1PcInstance pc = iterator.next();
      pc.sendPackets(packet);
    } 
  }
  
  public List<L1PcInstance> getRandomPlayers(int count) {
    try {
      Collection<L1PcInstance> tempList = getAllPlayers();
      if (!tempList.isEmpty()) {
        L1PcInstance[] userList = tempList.<L1PcInstance>toArray(new L1PcInstance[tempList.size()]);
        List<L1PcInstance> newList = new ArrayList<>();
        Random _random = new Random();
        while (newList.size() < count) {
          L1PcInstance each_pc = userList[_random.nextInt(userList.length)];
          if (each_pc != null && !newList.contains(each_pc))
            newList.add(each_pc); 
        } 
        return newList;
      } 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
    return null;
  }
  
  public void addMap(int mapid) {
    ConcurrentHashMap<Integer, L1Object> map = new ConcurrentHashMap<>();
    this._visibleObjects.put(Integer.valueOf(mapid), map);
  }
  
  public L1PcInstance[] getAllPlayersToArray() {
    return (L1PcInstance[])this._allPlayers.values().toArray((Object[])new L1PcInstance[this._allPlayers.size()]);
  }
  
  public L1PcInstance getPlayer(int objid) {
    Iterator<L1PcInstance> iterator = getAllPlayers().iterator();
    while (iterator.hasNext()) {
      L1PcInstance each = iterator.next();
      if (each.getId() == objid)
        return each; 
    } 
    return null;
  }
  
  public int getObjId(L1Npc npc) {
    Iterator<L1Object> iterator = this._allObjects.values().iterator();
    while (iterator.hasNext()) {
      L1Object obj = iterator.next();
      if (obj instanceof L1NpcInstance && ((L1NpcInstance)obj).getNpcTemplate().get_npcId() == npc.get_npcId())
        return obj.getId(); 
    } 
    return 0;
  }
}
